#include "Server.h"
#include <QDebug>
#include <QJsonParseError>
#include <QJsonObject>
#include <QNetworkConfiguration>


Server* Server::m_inst  = nullptr;

Server::Server(QObject *parent) : QObject(parent)
{
    m_net  = new QNetworkAccessManager(this);
    QNetworkConfiguration  config(m_net->configuration() );
    config.setConnectTimeout(2000);
    m_net->setConfiguration(config);
}

Server *Server::getInstance()
{
    if(m_inst){
        return m_inst;
    }
    else{
        m_inst  = new Server();
        return m_inst;
    }
}

void Server::setHost(const QString &host)
{
    m_host  = host;
}


void Server::requestStudentId(const QString &braceletSn)
{
    //if(m_mapper.contains(braceletSn) == false){
        QNetworkRequest  request;


        request.setUrl( "http://" + m_host + "/bracelets/" + braceletSn);
        QNetworkReply * reply  = m_net->get(request);
        connect(reply, SIGNAL(finished()), this, SLOT(handleBraceletReply()));
}


void Server::pushScore(const QString &hardwareSn, const qint64 &studentId, int score)
{
    qDebug() << "PushScore";
    QNetworkRequest request;
    request.setUrl("http://" + m_host + "/scores");
    qDebug() << request.url().path();
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QJsonObject item;
    item.insert("hardwareId", hardwareSn);
    item.insert("studentId", studentId);
    item.insert("score", score);

    QNetworkReply * reply  = m_net->post(request, QJsonDocument(item).toJson());
    connect(reply, SIGNAL(finished()), this, SLOT(handleScoreReply()));
}



void Server::handleReplyError(QNetworkReply::NetworkError code)
{
    qDebug() << "Error code" << code;
}

void Server::handleBraceletReply()
{
    QNetworkReply * reply  = dynamic_cast<QNetworkReply*>(sender());

    int statusCode  = 0;

    const QVariant statusCodeTarget  = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if(statusCodeTarget.isValid()){
        statusCode  = statusCodeTarget.toInt();
    }
    qDebug() << "Status code" << statusCode;

    if(200 != statusCode){
         emit requestStudentIdFailed(statusCode, "查询手环用户错误");
         reply->deleteLater();
         return;
    }


    QByteArray  ba  = reply->readAll();
    qDebug() << ba;
    QJsonParseError jsonErr;
    QJsonDocument json  = QJsonDocument::fromJson(ba, &jsonErr);
    if(jsonErr.error == QJsonParseError::NoError){
        if(json.isObject()){
           const QJsonObject jsonObj  = json.object();
           if(jsonObj.contains("item")){
               QJsonObject item = jsonObj.value("item").toObject();
               if(item.contains("studentId")){
                   emit requestStudentIdSuccessed(item.value("braceletId").toString(), item.value("studentId").toInt());
               }
               else{
                   emit requestStudentIdFailed(100, "无效手环");
               }
           }
           else{
               emit requestStudentIdFailed(110, "服务器返回错误");
           }
        }
        else{
            emit requestStudentIdFailed(110, "服务器返回格式错误");
        }
    }
    else{
        emit requestStudentIdFailed(110, "服务器返回格式错误");
    }

    reply->deleteLater();
}


void Server::handleScoreReply()
{
    QNetworkReply * reply  = dynamic_cast<QNetworkReply*>(sender());

    int statusCode  = 0;

    const QVariant statusCodeTarget  = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if(statusCodeTarget.isValid()){
        statusCode  = statusCodeTarget.toInt();
    }
    qDebug() << "Status code" << statusCode;

    if(200 != statusCode){
         emit pushScoreFailed(statusCode, "分数上传错误");
         reply->deleteLater();
         return;
    }

    QByteArray  ba  = reply->readAll();
    QJsonParseError  jsonErr;
    QJsonDocument json  = QJsonDocument::fromJson(ba, &jsonErr);
    if(jsonErr.error == QJsonParseError::NoError){
        if(json.isObject()){
            const QJsonObject jsonObj  = json.object();
            if(jsonObj.contains("item")){
                QJsonObject item  = jsonObj.value("item").toObject();
                if(item.contains("studentId")){
                    qint64 studentId  = item.value("studentId").toInt();
                    emit pushScoreSuccessed(studentId);
                }
                else{
                    emit pushScoreFailed(100, "服务器返回内容错误");
                }
            }
            else{
                emit pushScoreFailed(100, "服务器返回内容错误");
            }
        }
        else{
            emit pushScoreFailed(110, "服务器返回格式错误");
        }
    }
    else{
        emit pushScoreFailed(110, "服务器返回格式错误");
    }

    reply->deleteLater();
}
